use crate::config::verify;
use clap::Parser;
use std::str::FromStr;

#[derive(Parser, Debug)]
#[command(author="ws", version="0.0.1", about="doc", long_about = None)]
#[command(next_line_help = true)]
pub struct Opts {
    #[command(subcommand)]
    pub subcmd: Subcommand,
}

#[derive(Parser, Debug)]
pub enum Subcommand {
    Get(Get),
    Post(Post),
    Put(Put),
    Delete(Delete),
}

/// GET
#[derive(Parser, Debug)]
pub struct Get {
    /// HTTP 请求的 URL
    #[arg(value_parser =  verify::parse_url)]
    pub url: String,
}

/// POST
#[derive(Parser, Debug)]
pub struct Post {
    /// HTTP 请求的 URL
    #[arg(value_parser = verify::parse_url)]
    pub url: String,
    /// HTTP 请求的 body
    pub body: Vec<KvPair>,
}

/// PUT
#[derive(Parser, Debug)]
pub struct Put {
    /// HTTP 请求的 URL
    #[arg(value_parser =  verify::parse_url)]
    pub url: String,
    /// HTTP 请求的 body
    #[arg(value_parser =  verify::parse_kv_pair)]
    pub body: Vec<KvPair>,
}

/// DELETE
#[derive(Parser, Debug)]
pub struct Delete {
    /// HTTP 请求的 URL
    #[arg(value_parser =  verify::parse_url)]
    pub url: String,
}

#[derive(Debug, Clone)]
pub struct KvPair {
    pub key: String,
    pub value: String,
}

impl FromStr for KvPair {
    type Err = String;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let mut split = s.split("=");
        println!("split: {:?}", split);
        let err = || format!("参数格式不正确: {}", s);
        Ok(Self {
            // 从迭代器中取第一个结果作为 key，迭代器返回 Some(T)/None
            // 我们将其转换成 Ok(T)/Err(E)，然后用 ? 处理错误
            key: split.next().ok_or_else(err)?.to_string(),
            // 从迭代器中取第二个结果作为 value
            value: split.next().ok_or_else(err)?.to_string(),
        })
    }
}
